from flask import Flask, request, jsonify
from PIL import Image, ImageDraw, ImageFont
import win32print
import win32ui
from PIL import ImageWin
import os
import textwrap
from datetime import datetime
import win32con
import re

app = Flask(__name__)


def generate_shipping_label(json_data, output_folder="./labels"):
    """生成货运标签图片"""
    # 确保输出文件夹存在
    os.makedirs(output_folder, exist_ok=True)

    # 打印机参数 (SATO CL4NX Plus 203dpi)
    DPI = 203
    WIDTH_MM, HEIGHT_MM = 76, 130  # 标签尺寸76×130mm
    width_px = int(WIDTH_MM * DPI / 25.4)
    height_px = int(HEIGHT_MM * DPI / 25.4)

    # 创建白色背景图片 (1-bit黑白模式)
    image = Image.new("1", (width_px, height_px), 1)
    draw = ImageDraw.Draw(image)

    # 加载字体 (Windows系统)
    try:
        font_2large = ImageFont.truetype("msyh.ttc", 40)
        font_large = ImageFont.truetype("msyh.ttc", 28)
        font_medium = ImageFont.truetype("msyh.ttc", 22)
        font_small = ImageFont.truetype("msyh.ttc", 18)
    except:
        font_large = ImageFont.load_default()
        font_medium = ImageFont.load_default()
        font_small = ImageFont.load_default()

    # 解析JSON数据
    order_id = json_data.get("order_id", "")
    items = json_data.get("items", [])
    payment = json_data.get("payment", {})
    customer = json_data.get("customer", {})
    task_info = json_data.get("task_info", {})
    order_count = json_data.get("order_count", 0)
    notes = json_data.get("notes", "")
    platform = json_data.get("platform", {})

    # 当前时间
    current_time = datetime.now().strftime("%Y/%m/%d %H:%M")

    y_position = 60

    # 1. 标题（保持不变）
    draw.text((width_px // 2, y_position), "机器人闪电仓出货单", font=font_2large, anchor="mt", fill=0)

    y_position += 60
    draw.text((width_px // 2, y_position), f"#{order_count}{platform}", font=font_2large, anchor="mt", fill=0)
    y_position += 40
    draw.text((width_px // 2, y_position), "分拣-A1", font=font_2large, anchor="mt", fill=0)
    y_position += 40
    draw.text((width_px // 2, y_position), "----------------------------------------------------", font=font_large,
              anchor="mt",
              fill=0)
    y_position += 10
    # 2. 顾客信息
    district_part, detail_part = format_address(customer.get('address'))
    draw.text((20, y_position), f" {district_part}", font=font_2large, fill=0)
    y_position += 40
    draw.text((20, y_position), f" {detail_part}", font=font_2large, fill=0)
    y_position += 40
    draw.text((20, y_position), f" {customer.get('name', '')}", font=font_2large, fill=0)
    y_position += 40
    draw.text((20, y_position), f" {customer.get('phone', '')}", font=font_2large, fill=0)
    y_position += 40
    draw.text((20, y_position), f" {current_time}", font=font_large, fill=0)
    y_position += 40
    draw.text((width_px // 2, y_position), "----------------------------------------------------", font=font_large,
              anchor="mt",
              fill=0)
    y_position += 10

    # 2. 订单信息
    draw.text((30, y_position), f"分拣机器人: {task_info.get('robot_name', '')}", font=font_medium, fill=0)
    y_position += 25
    # 2. 订单信息
    draw.text((30, y_position), f"分拣任务号: {task_info.get('task_id', '')}", font=font_medium, fill=0)
    y_position += 35
    # 计算 items 中所有商品的 quantity 总和
    total_quantity = sum(item.get('quantity', 0) for item in items)

    draw.text((width_px // 2, y_position),
              f"----------------------------拣货商品件数{total_quantity}---------------------------", font=font_large,
              anchor="mt",
              fill=0)
    y_position += 25

    # 3. 商品信息
    for item in items:
        # 商品名称和数量
        item_text = f"{item.get('name', '')} "
        quantity = f"×{item.get('quantity', 0)}"

        draw.text((30, y_position), item_text, font=font_medium, fill=0)
        draw.text((550, y_position), quantity, font=font_medium, fill=0)
        y_position += 25
    y_position += 10
    draw.text((width_px // 2, y_position), "----------------------------------------------------", font=font_large,
              anchor="mt",
              fill=0)

    y_position += 15

    # 4. 支付信息
    draw.text((30, y_position), f"订单编号{order_id}", font=font_medium, fill=0)
    y_position += 25
    draw.text((30, y_position), f"商品总额: ¥{payment.get('total', 0)}", font=font_medium, fill=0)

    draw.text((420, y_position), f"实付金额: ¥{payment.get('actual_pay', 0)}", font=font_medium, fill=0)
    y_position += 30
    draw.text((width_px // 2, y_position), "----------------------------------------------------", font=font_large,
              anchor="mt",
              fill=0)
    draw.text((20, y_position), f"【顾客备注】", font=font_2large, fill=0)
    y_position += 40
    draw.text((30, y_position), f"{notes}", font=font_2large, fill=0)
    y_position += 40

    draw.text((20, height_px - 80),
              "------------------------------------------------------------------------------------------------------------------",
              font=font_large,
              anchor="mt",
              fill=0)
    # 7. 打印时间
    draw.text((30, height_px - 70), f"打印时间: {current_time}", font=font_small, fill=0)

    # 保存文件
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"订单_{order_id}_{timestamp}.bmp"
    output_path = os.path.join(output_folder, filename)
    image.save(output_path)

    return output_path


def print_label(image_path):
    """打印功能"""
    try:
        # 1. 打开图片
        image = Image.open(image_path)

        # 2. 获取默认打印机
        printer_name = win32print.GetDefaultPrinter()

        # 3. 创建打印设备上下文
        hdc = win32ui.CreateDC()
        hdc.CreatePrinterDC("SATO CL4NX Plus 203dpi")

        # 4. 开始打印任务
        hdc.StartDoc("Print Job")
        hdc.StartPage()

        # 5. 打印图片（自动适应页面大小）
        dib = ImageWin.Dib(image)
        dib.draw(hdc.GetHandleOutput(),
                 (0, 0, hdc.GetDeviceCaps(win32con.HORZRES), hdc.GetDeviceCaps(win32con.VERTRES)))

        # 6. 结束打印
        hdc.EndPage()
        hdc.EndDoc()

        return True, f"已发送打印任务到: {printer_name}"

    except Exception as e:
        return False, f"打印失败: {str(e)}"


def format_address(addr):
    """分割处理地址"""
    if not addr:
        return "", ""

    # 去除任何省和市（使用正则表达式匹配）
    addr = re.sub(r'(.*?省|.*?市|.*?区)', '', addr)

    # 分割区和详细地址
    match = re.search(r'(\d.*)', addr)
    if match:
        detail_part = match.group(1)  # 门牌号及其之后的部分
        addr_part = addr[:match.start()].strip()  # 门牌号之前的部分
    else:
        addr_part = addr.strip()
        detail_part = ""

    # 处理detail_part中的换行符和空格
    detail_part = detail_part.replace("\n", " ").strip()

    return addr_part, detail_part


@app.route('/print_shipping_label', methods=['POST'])
def handle_print_request():
    """处理打印请求的API接口"""
    try:
        # 获取JSON数据
        data = request.get_json()

        if not data:
            return jsonify({"status": "error", "message": "No data provided"}), 400

        # 生成标签
        
        
        label_path = generate_shipping_label(data)

        # 打印标签
        success, message = print_label(label_path)

        if success:
            return jsonify({
                "status": "success",
                "message": message,
                "label_path": label_path
            }), 200
        else:
            return jsonify({
                "status": "error",
                "message": message,
                "label_path": label_path
            }), 500

    except Exception as e:
        return jsonify({
            "status": "error",
            "message": f"处理请求时发生错误: {str(e)}"
        }), 500


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8081,debug=True)